//1.js的数据类型有种划分：
//原始数据类型 Number Boolean String null undefined Symbol
//引用数据类型。 Object Array Function Date RegExp...


//2.类型转换
//显示类型转换
console.log(Number('12'));
//被认定为false的值 undefined， null， NaN， ''， 0， false
console.log(Boolean(''));
console.log(Boolean('0'));
console.log(String(undefined));
console.log(String(123));

// == ===异同 隐式类型转换
console.log(typeof(null));
console.log(typeof(undefined));
console.log(typeof(NaN));
console.log(1 == '1');
console.log(1 === '1');
console.log(NaN === NaN);
console.log(null === null);
console.log(33 + '11' * 2);
console.log(2 > 3 < 1);
console.log(10 > 100 > 0);

// 3.数组 
//迭代forEach map filter reduce some every

var arr = [1,2,3,4,5,6,7];
console.log(arr[10]);
arr.length = 5;
console.log(arr);

//升降序，随机排序
arr.sort((a, b) =>  {
	return a - b; //升序
	return b - a; //降序
	return Math.random() - 0.5; //随机排序
})
console.log(arr);

// 4.Function
// 'abc' => 'a b c'  
function spacy(str) {
	return str.split('').join(' ');
}
//原型
String.prototype.spacy = function() {
	return this.split('').join(' ');
}

// call apply 异同: 作用，改变this指向 区别，后面传的参数形式不同
//自定义log函数
function myLog() {
	console.log.apply(console, arguments);
}

var a = {name: 'aaaaaaaaaaaaa'}
var b = {name: 'bbbbbb'};
function sayName() {
	console.log(this.name);
}
sayName.call(a)
sayName.call(b)

//
var a = {name: 'aaaaaaaaaaaaa'};
var bob = {
	name: 'Bob',
	sayName: function(friend = '') {
		console.log('Hi!' + friend + ',My name is: ' + this.name)
	}
}
bob.sayName();
var sayN = bob.sayName;
sayN();
sayN.call(a, 'David');
sayN.apply(a, ['David']);
sayN.apply(a);
sayN.apply(b);


/////////////////////////////////////
var name = '222';
var a = {
	name: '111',
	say: function() {
		console.log(this.name)
	}
}
var b = {
	name: '333',
	say: function(fn) {
		fn();
	}
}
a.say();
var fn = a.say();
fn();
b.say(a.say);
b.say = a.say;
b.say();

// 作用域 作用域链，变量提升
var a = 100;
var b = 200;
function test(a , b){
	console.log(a); //f a() {}
	console.log(b); //undefined
	var b = 234;
	console.log(b);	//234
	a = 123;
	console.log(a);	//123
	function a (){};
	var a;
	b = 234;
	var b = function(){};
	console.log(a);	//123
	console.log(b);	//f() {}
}
test(1);

/////////////////////////
console.log(test);
function test(test){
	console.log(test);
	var test = 234;
	console.log(test);
	function test(){
	}
}
test(1);
var test = 123;

// 闭包
function a() {
	function b() {
		var bb = 234;
		console.log(aaa);
	}
	var aaa = 123;
	return b;
}

var glob = 100;
var demo = a();

demo();



//打印出 100 以内的质数（从 1 除到他本身，只能有两个因数）
var count = 0; // 用于计数
for (var i = 2; i < 100; i++) {
	// for (var j = 1; j <= i: j++)
	for (var j = 1; j <= Math.sqrt(i); j++) {
		if (i % j == 0) {
			count++;
		}
	}
	if (count == 1) {
		console.log('质素：', i)
	}
	//计数归0
	count = 0;
}

//对象，键值对转换
// hasOwnProperty
// in
// 键值对转换
var o = {a: 12, b: 23};
function trans(obj) {
	var b = {};
	for(var key in obj) {
		b[obj[key]] = key;
	}
	return b;
}

var b = trans(o);
console.log(b);

// 微任务 宏任务 事件循环
(function() {
	setTimeout(() => {
		console.log(1);
	}, 0);
	new Promise(function(resolve, reject) {
		console.log(2);
		for (var i = 0; i < 10000; i++) {
			i == 9999 && resolve();
		}
		console.log(3);
	}).then(function() {
		console.log(4);
	})
	console.log(5);
}())

//2 3 5 4 1